package org.farming.plants;
/**
 * Flower, Plant class
 * @author DEADBEEF
 * @version 0.01a
 * @note Needs to test
**/
public class Bushes extends Plants
{
    public static enum Bush implements Plants.PlantEnum {
      UNKNOWN     ( -3, "Unknown",          0,  0, 0,     "Unknown",           0,    "Unknown",           "",                 false ), 
      NONE        ( -2, "None",             0,  0, 0,     "None",              0,    "None",              "Bush Patch",       false ), 
      WEEDS       ( -1, "Weeds",            0,  0, 0,     "Weeds",             6055, "Weeds",             "Bush Patch",       false ), 
      EMPTY       ( 0,  "Empty",            0,  0, 0,     "Empty",             0,    "Empty",             "Bush Patch",       false ), 
      REDBERRY    ( 4,  "Redberry",         10, 7, 5101,  "Redberry seed",     1951, "Redberries",        "Redberry bush",    true  ), 
      CADAVABERRY ( 14, "Cadavaberry",      22, 7, 5102,  "Cadavaberry seed",  753,  "Cadava berries",    "Cadavaberry bush", true  ), 
      DWELLBERRY  ( 25, "Dwellberry",       36, 8, 5103,  "Dwellberry seed",  2126, "Dwellberries",       "Swellberry bush",  true  ), 
      JANGERBERRY ( 37, "Jangerbery",       48, 9, 5104,  "Jangerberry seed", 247,  "Jangerberries",      "Jangerberry bush", true  ),
      WHITEBERRY  ( 50, "Whiteberry",       59, 9, 5105,  "Whiteberry seed",  239,  "White berries",      "Whiteberry bush",  true  ),
      POISON_IVY  ( -4, "Poison Ivy",       70, 9, 5106,  "Poison ivy seed",  6018, "Poison ivy berries", "Poison Ivy bush",  true  );
      
        private final int id, level, stages, seedId, itemId;   
        private final String seedString, itemString, interactString, name;   
        private final boolean canNote; 

        /**
         * Bush Enum
         * Interface params
         * @param id Our unique id and offset for the plant
         * @param name The reference for this plant which we can display to the user
         * @param level The farming level required to plant
         * @param stages How many growth stages the plant has (from first planted to harvestable inclusive)
         * @param seedId, Item id of the seed
         * @param seedString, Item string of the seed
         * @param itemId, Item id of the harvested plant
         * @param itemString, Item string of the harvested plant
         * @param interactString, String of the plant when grown
         * @param canNote, Whether the leprechaun can note this plant (noted item id's are +1 of the regular id)
         * Local params
        **/
        Bush(
            int id, 
            String name,
            int level, 
            int stages, 
            int seedId, 
            String seedString, 
            int itemId, 
            String itemString, 
            String interactString, 
            boolean canNote
        ) {
            this.id              = id;
            this.name            = name;
            this.level           = level;
            this.stages          = stages;
            this.seedId          = seedId;
            this.itemId          = itemId;
            this.seedString      = seedString;
            this.itemString      = itemString;
            this.interactString  = interactString;
            this.canNote         = canNote;
        }
        
        //Interface methods
        public int id()                 {return id;}
        public int level()              {return level;}
        public int stages()             {return stages;}
        public int seedId()             {return seedId;}
        public int itemId()             {return itemId;}
        public String seedString()      {return seedString;}
        public String itemString()      {return itemString;}
        public String interactString()  {return interactString;}
        public boolean canNote()        {return canNote;}
        public int noteId()             {return canNote?(itemId+1):itemId;}
        public String toString()        {return name;}
        //Local methods
    }

   /**
    * This was designed to be a static method, however static and abstract don't mix so this will have to do
    * 
    * @param bits The byte for the herb patch we want the state for
    * @return The calculated state enum
   **/
    public State getState(int bits)
    {
        bits = bits&255;//Cleanse
        int stateBits = (bits&192)>>6;//Get 7&8th bits
        int plantBits = bits&63;//Clear 7&8th bits
        if(stateBits==0x00){
            Bush p = getPlant(bits);
            if(getStagePlant(p,bits)==p.stages()){      return State.READY;
            }else{                                      return State.GROWING;}
        }else if(stateBits==0x01){                      return State.DISEASED;
        }else if(stateBits==0x02){                      return State.DEAD;
        }else if(stateBits==0x03){ 
            if(plantBits>=0x3A&&plantBits<=0x3F){       return State.CHECK_HEALTH;
            }else if(plantBits>=0x05&&plantBits<=0x0C){ return State.GROWING;     //Poison ivy special case
            }else{                                      return State.READY;}      //Poison ivy special case
        }else{                                          return State.UNKNOWN;}
   }
   
   /**
    * This was designed to be a static method, however static and abstract don't mix so this will have to do
    * 
    * @param bits The byte for the herb patch we want the plant for
    * @return The calculated plant enum
   **/
    public Bush getPlant(int bits)
    {
        bits = bits&255;//Cleanse
        int stateBits = (bits&192)>>6;//Get 7&8th bits
        int plantBits = bits&63;//Clear 7&8th bits
        if((stateBits==0)&&((plantBits==0x03))){                         return Bush.EMPTY;
        }else if((stateBits==0)&&(plantBits>=0x00)&&(plantBits<=0x02)){  return Bush.WEEDS;
        }else if((stateBits==0x03)){
            if((plantBits>=0x05)&&(plantBits<=0x11)||(plantBits==0x3F)){ return Bush.POISON_IVY;
            }else if(plantBits==0x3A){                                   return Bush.REDBERRY;
            }else if(plantBits==0x3B){                                   return Bush.CADAVABERRY;
            }else if(plantBits>=0x3C){                                   return Bush.DWELLBERRY;
            }else if(plantBits>=0x3D){                                   return Bush.JANGERBERRY;
            }else if(plantBits>=0x3E){                                   return Bush.WHITEBERRY;
            }else{                                                       return Bush.UNKNOWN;}
        }else if((plantBits>=0x05)&&(plantBits<=0x0E)){                  return Bush.REDBERRY;
        }else if((plantBits>=0x0F)&&(plantBits<=0x19)){                  return Bush.CADAVABERRY;
        }else if((plantBits>=0x1A)&&(plantBits<=0x25)){                  return Bush.DWELLBERRY;
        }else if((plantBits>=0x26)&&(plantBits<=0x32)){                  return Bush.JANGERBERRY;
        }else if((plantBits>=0x33)&&(plantBits<=0x3F)){                  return Bush.WHITEBERRY;
        }else{                                                           return Bush.UNKNOWN;}
    }
   
   /**
    * This was designed to be a static method, however static and abstract don't mix so this will have to do
    * 
    * @param bits The byte for the herb patch we want the stage for
    * @return The calculated stage
   **/
    public int getStage(int bits)
    {
        bits = bits&255;//Cleanse
        int plantBits = bits&63;//Clear 7&8th bits
        return getStagePlant(getPlant(bits), bits);
    }
    private int getStagePlant(Bush plant, int bits)
    {
        switch(plant)
        {
            case EMPTY:
            case WEEDS:
            case UNKNOWN:
                return 0;
            default:
                int stateBits = (bits&192)>>6;//Get 7&8th bits
                int plantBits = bits&63;//Clear 7&8th bits
                if(stateBits==0x03)
                {
                    if(plantBits>=0x05&&plantBits<=0x0C)
                    {
                        return(plantBits+plant.id()>plant.stages())?plant.stages():plantBits+plant.id();//Poison ivy special case (has negative offset to keep unique with redberry)
                    }
                    else
                    {
                        return plant.stages();//Check health
                    }
                }
                else
                {
                    return (plantBits-plant.id()>plant.stages())?plant.stages():plantBits-plant.id();
                }
        }
    }
    
   /**
    * This was designed to be a static method, however static and abstract don't mix so this will have to do
    * 
    * @param bits The byte for the bush patch we want the number of berries for
    * @return The calculated number of berries that can be picked, returns -1 in cases where we can't work it out
   **/
    public int getBerryCount(int bits)
    {
        bits = bits&255;//Cleanse
        int stateBits = (bits&192)>>6;//Get 7&8th bits
        int plantBits = bits&63;//Clear 7&8th bits
        if((stateBits==0x03)&&(plantBits>=0x3A)&&(plantBits<=0x3F)){return 4;} //Check Health (so when they reach and check health it will have 4)
        Bush bush = getPlant(bits);
        switch(bush)
        {
            case REDBERRY:    return ((plantBits-0x0A)>=0)?(plantBits-0x0A):0;
            case CADAVABERRY: return ((plantBits-0x15)>=0)?(plantBits-0x0A):0;
            case DWELLBERRY:  return ((plantBits-0x21)>=0)?(plantBits-0x0A):0;
            case JANGERBERRY: return ((plantBits-0x2E)>=0)?(plantBits-0x0A):0;
            case WHITEBERRY:  return ((plantBits-0x3B)>=0)?(plantBits-0x0A):0;
            case POISON_IVY:  return ((plantBits-0x0D)>=0)?(plantBits-0x0A):0;
            default:          return -1;//Unknown, -1 to show
        }
    }
}
/*
##Locations (Where byte n is mentioned this is rtl so 4321)
Setting 509, 
byte 1 varrock, 
byte 2 rimmington,
byte 3 misclenia
byte 4 monastry
format: sspp pppp
- plant types and growth states (p bits):
-- 0x00 - 0x03: Empty        (0x00-0x03 3-0 weeds iff ss==00)
-- 0x05 - 0x0E: Red berry    (0x05-0x09 stage 1-6, 0x0A-0x0E 0-4 berries, [0x3A Check Health] iff ss==0x03)
-- 0x0F - 0x19: Cadava berry (0x0F-0x14 stage 1-6, 0x15-0x19 0-4 berries, [0x3B Check Health] iff ss==0x03)
-- 0x1A - 0x25: Dwell berry  (0x1A-0x20 stage 1-7, 0x21-0x25 0-4 berries, [0x3C Check Health] iff ss==0x03)
-- 0x26 - 0x32: Janger berry (0x26-0x2D stage 1-8, 0x2E-0x32 0-4 berries, [0x3D Check Health] iff ss==0x03)
-- 0x33 - 0x3F: White berry  (0x33-0x3A stage 1-8, 0x3B-0x3F 0-4 berries, [0x3E Check Health] iff ss==0x03)
-- 0x05 - 0x22: Poison ivy  ([0x05-0x0C stage 1-8, 0x0D-0x11 0-4 berries,  0x3F Check Health] iff ss==0x03)
Poison ivy is immune to being diseased and therefore dying
- states (s bits):
- 0x00: growing
- 0x01: diseased
- 0x02: dead
- 0x03 and plant bits 0x3A - 0x3F: Check Health
##red berry (7? stages) wikia says 6
00000101 - stage 1
00000110 - stage 2
00000110 - stage 3
00000111 - stage 4
00001000 - stage 5
00001001 - stage 6
11111010 - check health 0x3a
00001010 - 4
00001101 - 3
00001100 - 2
00001011 - 1
00001010 - 0
##White Berry (9 stages)
??110011 - stage 1
10110100 - dead stage 1
11111110 - Check health 0x3e
00111111 - 4
00111110 - 3
00111101 - 2
00111100 - 1
00111011 - 0 (counting down)
##Janger (9 stages)
00100110 - stage 1
00100111 - stage 2?
00101000 - stage 3?
00101001 - stage 4?
00101010 - stage 5?
00101011 - stage 6?
00101100 - stage 7?
00101101 - stage 8?
11111101 - check health 0x3d
00110010 - full

##poison (9 stages)
11000101 - stage 1
11001010 - check health?
11010001 - 4 berry
11010000 - 3
11001111 - 2
11001110 - 1
11001101 - 0 (counting down)
##dwell (8 stages)
00011010 - stage 1
00011011 - stage 2?
00011100 - stage 3?
00011101 - stage 4?
00011110 - stage 5?
00011111 - stage 6?
00100000 - stage 7?
11111100 - check health 0x3c
00100101 - full
##cadava
00001111 - stage 1
11111011 - check health 0x3b
*/